package com.itheima.pinda.zuul.filter;

import com.itheima.pinda.auth.client.properties.AuthClientProperties;
import com.itheima.pinda.auth.client.utils.JwtTokenClientUtils;
import com.itheima.pinda.auth.utils.JwtUserInfo;
import com.itheima.pinda.base.R;
import com.itheima.pinda.context.BaseContextConstants;
import com.itheima.pinda.exception.BizException;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;


/**
 * @Description: jwt令牌解析 过滤器,将解析到的用户信息放入zuul请求头中
 * @Author: ysf
 * @CreateTime: 2024-11-14  14:47
 * @Version: 1.0
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class TokenContextFilter extends BaseFilter {

    final AuthClientProperties authClientProperties;
    final JwtTokenClientUtils jwtTokenClientUtils;

    /**
     * 设置过滤器类型：前置过滤器
     *
     * @param
     * @return java.lang.String
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**
     * 过滤器执行的顺序 数值越大优先级越低
     *
     * @param
     * @return int
     */
    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
    }

    /**
     * 是否执行过滤器
     *
     * @param
     * @return boolean
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 过滤器执行逻辑
     *
     * @param
     * @return java.lang.Object
     */
    @Override
    public Object run() throws ZuulException {
        //1、判断是否需要鉴权
        if (getIgnoreToken()) {
            return null;
        }
        //2、请求头中获取token 解析jwt令牌
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        //读取token
        String token = request.getHeader(authClientProperties.getUser().getHeaderName());


        log.info("jwt令牌：{}",token);

        //解析token
        JwtUserInfo userInfo = null;

        //解析会出现的异常，需要手动抛出
        try {
            userInfo = jwtTokenClientUtils.getUserInfo(token);
        } catch (BizException e) {
            errorResponse(e.getMessage(), e.getCode(), 200);
            return null;
        } catch (Exception e) {
            errorResponse("解析token失败!", R.FAIL_CODE, 200);
            return null;
        }

        //封装用户信息到zuul请求头中
        if (userInfo != null) {
//            currentContext.addZuulResponseHeader(BaseContextConstants.JWT_KEY_NAME,userInfo.getName());
//            currentContext.addZuulResponseHeader(BaseContextConstants.JWT_KEY_ACCOUNT,userInfo.getAccount());
//            currentContext.addZuulResponseHeader(BaseContextConstants.JWT_KEY_ORG_ID, String.valueOf(userInfo.getOrgId()));
//            currentContext.addZuulResponseHeader(BaseContextConstants.JWT_KEY_STATION_ID, String.valueOf(userInfo.getStationId()));
//            currentContext.addZuulResponseHeader(BaseContextConstants.JWT_KEY_USER_ID, String.valueOf(userInfo.getUserId()));
            addHeader(currentContext, BaseContextConstants.JWT_KEY_NAME, userInfo.getName());
            addHeader(currentContext, BaseContextConstants.JWT_KEY_USER_ID, userInfo.getUserId());
            addHeader(currentContext, BaseContextConstants.JWT_KEY_STATION_ID, userInfo.getStationId());
            addHeader(currentContext, BaseContextConstants.JWT_KEY_ORG_ID, userInfo.getOrgId());
            addHeader(currentContext, BaseContextConstants.JWT_KEY_ACCOUNT, userInfo.getAccount());
        }

        return userInfo;
    }

    //封装用户信息到zuul请求头中
    public void addHeader(RequestContext context, String name, Object value) {
        if (StringUtils.isEmpty(value)) {
            return;
        }
        context.addZuulResponseHeader(name, String.valueOf(value));
    }
}
